﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Data.SqlClient;
//using System.Data.SQLite;
using System.Data.SQLite;

namespace DATA_SERVER
{
    class ZKPUSH_Service : Service
    {
        private class ZKPUSH_Device
        {
            public string strSN = string.Empty;         //门禁机序列号
            public string RegCode = string.Empty;       //门禁机注册码
            public string SessionID = string.Empty;     //门禁机会话ID
            public string BeaconName = string.Empty;    //门禁机名称
            public string Position = string.Empty;      //门禁机排序号
            public int InOut = 0;                       //出入类型
            public int Delay = 0;                       //网络延时
            public Queue<string> CommandList = new Queue<string>();     //指令队列
            public readonly object _Commandlocker = new object();       //指令队列锁
            public bool Connected = false;              //连接状态
        }

        [Serializable]
        private class ZKPUSH_UserInfo
        {
            public string Password = String.Empty;              //密码
            public ZKPUSH_Data[] Finger = new ZKPUSH_Data[10];  //指纹
            public ZKPUSH_Data[] Face = new ZKPUSH_Data[12];    //人脸
        }

        [Serializable]
        private class ZKPUSH_Data
        {
            public string Size = String.Empty;      //大小
            public string Valid = String.Empty;     //有效性
            public string Buf = String.Empty;       //缓存
        }

        private static List<ZKPUSH_Device> DeviceList = new List<ZKPUSH_Device>();  //设备列表

        private TcpListener myListener;

        private const string REQUEST_METHOD_POST = "POST";
        private const string REQUEST_METHOD_GET = "GET";

        //服务启动
        public override void StartService()
        {
            isStop = false;

            Thread listenThread = new Thread(new ThreadStart(StartListen));
            listenThread.IsBackground = true;
            listenThread.Start();
        }

        //停止服务
        public override void StopService()
        {
            if (isStop)
            {
                return;
            }

            isStop = true;

            Thread.Sleep(1000);
            if (myListener != null)
            {
                myListener.Stop();
                myListener = null;
            }

            DeviceList.Clear();

            Data_Func.ShowText("已停止监听！");
        }

        //向门禁机发送新用户
        public override void AddUser(string pin, string name, string cardno, string type, string extra)
        {
            ZKPUSH_UserInfo userinfo;
            if ((type == "ZK") && (extra.Length > 0))
            {
                userinfo = Data_Func.Deserialize(extra) as ZKPUSH_UserInfo;         //反序列化
            }
            else
            {
                userinfo = new ZKPUSH_UserInfo();
            }

            //构造更新用户表user的语句
            string user = "DATA UPDATE user Pin=" + pin + "\t";
            if (cardno.Length > 0)
            {
                user += "CardNo=" + cardno + "\t";
            }
            else
            {
                user += "CardNo=0\t";
            }
            if (name.Length > 0)
            {
                user += "Name=" + name + "\t";
            }
            if (userinfo.Password.Length > 0)
            {
                user += "Password=" + userinfo.Password + "\t";
            }
            user = user + "StartTime=0\tEndTime=0";

            //构造更新用户权限表userauthorize的语句
            string authorize = "DATA UPDATE userauthorize Pin=" + pin + "\tAuthorizeTimezoneId=1";

            for (int i = 0; i < DeviceList.Count; i++)
            {
                while (DeviceList[i].CommandList.Count > 100)
                {
                    Thread.Sleep(10);
                }
                lock (DeviceList[i]._Commandlocker)
                {
                    //将语句加入指令队列，等待发送
                    DeviceList[i].CommandList.Enqueue(user);
                    DeviceList[i].CommandList.Enqueue(authorize);
                    for (int k = 0; k < 10; k++)
                    {
                        if (userinfo.Finger[k] != null)
                        {
                            //更新指纹表templatev10
                            DeviceList[i].CommandList.Enqueue("DATA UPDATE templatev10 Pin=" + pin + "\tFingerID=" + k + "\tSize=" + userinfo.Finger[k].Size + "\tValid=" + userinfo.Finger[k].Valid + "\tTemplate=" + userinfo.Finger[k].Buf);
                        }
                    }
                    for (int k = 0; k < 12; k++)
                    {
                        if (userinfo.Face[k] != null)
                        {
                            //更新人脸表facev7
                            DeviceList[i].CommandList.Enqueue("DATA UPDATE facev7 Pin=" + pin + "\tFaceID=" + k + "\tSize=" + userinfo.Face[k].Size + "\tValid=" + userinfo.Face[k].Valid + "\tFace=" + userinfo.Face[k].Buf);
                        }
                    }
                }
            }
        }

        //删除门禁机指定用户
        public override void DelUser(string pin)
        {
            for (int i = 0; i < DeviceList.Count; i++)
            {
                lock (DeviceList[i]._Commandlocker)
                {
                    //将删除用户表user、用户权限表userauthorize、指纹表templatev10、人脸表facev7等表中指定条目的指令加入指令队列
                    DeviceList[i].CommandList.Enqueue("DATA DELETE user Pin=" + pin);
                    DeviceList[i].CommandList.Enqueue("DATA DELETE userauthorize Pin=" + pin);
                    DeviceList[i].CommandList.Enqueue("DATA DELETE templatev10 Pin=" + pin);
                    DeviceList[i].CommandList.Enqueue("DATA DELETE facev7 Pin=" + pin);
                }
            }
        }

        //清空门禁机中所有用户
        public override void ClearUser()
        {
            for (int i = 0; i < DeviceList.Count; i++)
            {
                lock (DeviceList[i]._Commandlocker)
                {
                    //将清空用户表user、用户权限表userauthorize、指纹表templatev10、人脸表facev7、考勤记录表transaction等表的指令加入指令队列
                    DeviceList[i].CommandList.Enqueue("DATA DELETE user *");
                    DeviceList[i].CommandList.Enqueue("DATA DELETE userauthorize *");
                    DeviceList[i].CommandList.Enqueue("DATA DELETE templatev10 *");
                    DeviceList[i].CommandList.Enqueue("DATA DELETE facev7 *");
                    DeviceList[i].CommandList.Enqueue("DATA DELETE transaction *");
                }
            }
            for (int i = 0; i < DeviceList.Count; i++)
            {
                //等待指令发送完毕
                while (DeviceList[i].CommandList.Count > 0)
                {
                    Thread.Sleep(10);
                }
            }
        }

        //检测门禁机状态
        public override string CheckConnect()
        {
            string tmpstr = DeviceList.Count.ToString() + "\t";

            for (int i = 0; i < DeviceList.Count; i++)
            {
                DeviceList[i].Delay += Global.NetInterval;                      //每隔X秒，门禁机延时加上X秒，接收到门禁机数据包后则延时清0
                if ((DeviceList[i].Connected) && (DeviceList[i].Delay > 30))    //延时大于30，则门禁机状态改为已断开
                {
                    DeviceList[i].Connected = false;
                    Data_Func.ShowText("门禁设备 <" + DeviceList[i].BeaconName + "> 已断开");
                }
                tmpstr += DeviceList[i].BeaconName + "\t" + DeviceList[i].InOut + "\t" + (DeviceList[i].Connected ? "1" : "0") + "\t";  //构造门禁机状态字符串
            }

            return tmpstr;
        }

        //监听线程函数
        private void StartListen()
        {
            Socket mySocket = null;
            while (!isStop)
            {
                try
                {
                    myListener = new TcpListener(IPAddress.Any, Global.ServerPort);
                    myListener.Start();
                    Data_Func.ShowText("开始监听 " + Global.ServerPort + " 端口");
                    break;
                }
                catch
                {
                    Data_Func.ShowText("网络连接失败！");
                    Thread.Sleep(10000);
                    continue;
                }
            }

            while (!isStop)
            {
                try
                {
                    mySocket = myListener.AcceptSocket();
                }
                catch { }

                Thread receive_Thread = new Thread(new ParameterizedThreadStart(ReceiveDataFromSocket));
                receive_Thread.IsBackground = true;
                receive_Thread.Start(mySocket);
            }
        }

        //数据接收函数
        private void ReceiveDataFromSocket(object obj)
        {
            try
            {
                Socket mySocket = obj as Socket;
                byte[] bReceive = new byte[1024 * 20];
                int receiveLength = 0;

                if (mySocket == null)
                {
                    return;
                }

                if (mySocket.Available <= 0)
                {
                    Thread.Sleep(50);
                }

                while (mySocket.Available > 0)
                {
                    int tmplen = 0;

                    mySocket.ReceiveBufferSize = bReceive.Length;

                    tmplen = mySocket.Receive(bReceive, receiveLength, bReceive.Length - receiveLength, SocketFlags.None);

                    receiveLength += tmplen;

                    if (tmplen <= 0 || receiveLength >= bReceive.Length)
                    {
                        break;
                    }

                    Thread.Sleep(50);
                }

                byte[] databyte = new byte[receiveLength];

                Array.Copy(bReceive, databyte, receiveLength);

                Analysis(databyte, mySocket);
            }
            catch { }
        }

        //数据包解析函数
        private void Analysis(byte[] bReceive, Socket remoteSocket)
        {
            try
            {
                string strReceive = Encoding.GetEncoding("utf-8").GetString(bReceive, 0, bReceive.Length);      //将编码转换成utf-8，防止编码不同导致的错误

                if (string.IsNullOrEmpty(strReceive))
                {
                    return;
                }

                if (strReceive.IndexOf("/iclock/") < 0)     //检查首字符串标识
                {
                    return;
                }

                string MethodInfo = string.Empty;           //首字符串
                int ContentLen = 0;
                string[] ContentStr = new string[] { };

                string[] arrReceive = strReceive.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);   //字符串分割

                for (int i = 0; i < arrReceive.Length; i++)
                {
                    if (arrReceive[i].IndexOf("/iclock/") >= 0)
                    {
                        MethodInfo = arrReceive[i];                                     //首字符串
                    }
                    else if (arrReceive[i].IndexOf("Content-Length:") >= 0)
                    {
                        ContentLen = int.Parse(arrReceive[i].Substring(15).Trim());     //内容长度
                    }
                    else if (ContentLen > 0)
                    {
                        ContentStr = new string[arrReceive.Length - i];                 //内容字符串数组
                        for (int j = 0; j < ContentStr.Length; j++)
                        {
                            ContentStr[j] = arrReceive[i + j];
                        }
                        break;
                    }
                }

                string[] arrMethodField = MethodInfo.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                if (arrMethodField.Length < 3)
                {
                    return;
                }

                string RequestMethod = arrMethodField[0];    //请求类型 指POST或者GET

                string[] arrRequestParam = arrMethodField[1].Split(new char[] { '?', '&' }, StringSplitOptions.RemoveEmptyEntries);

                if (arrRequestParam.Length < 2)
                {
                    return;
                }

                string RequestCmd = arrRequestParam[0].Substring(8).Trim();

                string RequestParam_SN = string.Empty;
                if (arrRequestParam[1].IndexOf("SN=") >= 0)
                {
                    RequestParam_SN = arrRequestParam[1].Substring(3).Trim();       //门禁机序列号
                }

                ZKPUSH_Device pDevice = GetDevice(RequestParam_SN);                 //根据序列号查找门禁机

                if (pDevice == null)                                                //若未找到门禁机，则注册新门禁机
                {
                    pDevice = ProcessRegister(RequestParam_SN);
                }

                pDevice.Delay = 0;                                                  //延时归0
                if (!pDevice.Connected)                                             //如果门禁机状态由断开改为连接，则重新同步时间
                {
                    lock (pDevice._Commandlocker)
                    {
                        pDevice.CommandList.Enqueue("SET OPTION DateTime=" + GetTimeSecond());  //将设置时间指令加入指令队列
                    }
                    pDevice.Connected = true;
                    Data_Func.ShowText("门禁设备 <" + pDevice.BeaconName + "> 已连接");
                }

                if (RequestMethod == REQUEST_METHOD_GET)                            //请求类型为GET
                {
                    if (RequestCmd == "cdata")                                      //设备发起的请求服务器信息
                    {
                        if ((arrRequestParam.Length == 3) && (arrRequestParam[2].IndexOf("options=all") >= 0))
                        {
                            string tmpdata = string.Empty;
                            tmpdata += "ServerVersion=3.1.1\r\n";
                            tmpdata += "ServerName=ADMS\r\n";
                            tmpdata += "PushVerSion=3.2.0\r\n";
                            tmpdata += "RequestDelay=5\r\n";
                            tmpdata += "ErrorDelay=15\r\n";
                            tmpdata += "Realtime=1\r\n";
                            tmpdata += "SessionID=" + pDevice.SessionID;

                            SendReply(tmpdata, ref remoteSocket);                   //回复服务器信息字符串
                        }
                    }
                    else if (RequestCmd == "getrequest")                            //请求指令
                    {
                        if (pDevice.CommandList.Count > 0)
                        {
                            string tmpstr = string.Empty;
                            int count = 0;
                            while (count < 100)                                     //从指令队列中取最多100条指令构造字符串（总长度太长可能导致发送超时，所以只选择100条）
                            {
                                string command = null;
                                lock (pDevice._Commandlocker)
                                {
                                    if (pDevice.CommandList.Count > 0)
                                    {
                                        command = pDevice.CommandList.Dequeue();
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                if ((command == null) || (command.Length <= 0))
                                {
                                    continue;
                                }
                                tmpstr += "C:" + (++count) + ":" + command + "\r\n";
                            }
                            SendReply(tmpstr, ref remoteSocket);                    //回复包含多条指令的字符串
                            Data_Func.ShowText("成功向 <" + pDevice.BeaconName + "> 发送 " + count + " 条命令！");
                        }
                        else
                        {
                            SendReply("OK", ref remoteSocket);
                        }
                    }
                }
                else if (RequestMethod == REQUEST_METHOD_POST)                      //请求类型为POST
                {
                    if (RequestCmd == "registry")                                   //注册请求
                    {
                        string tmpdata = "RegistryCode=" + pDevice.RegCode;
                        SendReply(tmpdata, ref remoteSocket);                       //回复注册码
                    }
                    else if (RequestCmd == "push")                                  //注册成功后,设备发起的请求服务器信息
                    {
                        string tmpdata = string.Empty;
                        tmpdata += "ServerVersion=3.0.1\r\n";
                        tmpdata += "ServerName=ADMS\r\n";
                        tmpdata += "PushVerSion=3.2.0\r\n";
                        tmpdata += "RequestDelay=5\r\n";
                        tmpdata += "ErrorDelay=15\r\n";
                        tmpdata += "Realtime=1\r\n";
                        tmpdata += "SessionID=" + pDevice.SessionID;

                        SendReply(tmpdata, ref remoteSocket);
                    }
                    else if (RequestCmd == "cdata")                                 //设备主动上传数据
                    {
                        ProcessData(pDevice, arrRequestParam, ContentStr);          //解析表数据
                        SendReply("OK", ref remoteSocket);
                    }
                    else if (RequestCmd == "devicecmd")                             //设备回复指令执行结果
                    {
                        SendReply("OK", ref remoteSocket);
                    }
                    else if (RequestCmd == "querydata")                             //设备回复服务器发起的列出指定表数据的请求
                    {
                        ProcessData(pDevice, arrRequestParam, ContentStr);
                        SendReply("OK", ref remoteSocket);
                    }
                }
            }
            catch
            {
                SendReply("OK", ref remoteSocket);
            }
        }

        //注册新设备
        private ZKPUSH_Device ProcessRegister(string strSN)
        {
            ZKPUSH_Device pDevice = new ZKPUSH_Device();
            pDevice.strSN = strSN;
            pDevice.RegCode = createRegCode();              //生成注册码
            pDevice.SessionID = createSessionID();          //生成会话ID
            pDevice.BeaconName = "未知设备" + strSN;

            try
            {
                //根据门禁机序列号从本地数据库中读取门禁机名称、类型、排序号
                SQLiteDataReader reader = DB_SQLite.ExecuteReader(string.Format("SELECT [BeaconName],[BeaType],[Line] FROM [T_JC_Beacon] WHERE [BeaMac] = '{0}'", strSN));

                if (reader.Read())
                {
                    pDevice.BeaconName = reader[0].ToString();
                    if (reader[1].ToString() == "JZWZLY004")        //入井门禁
                    {
                        pDevice.InOut = 1;
                    }
                    else if (reader[1].ToString() == "JZWZLY005")   //出井门禁
                    {
                        pDevice.InOut = 2;
                    }
                    pDevice.Position = reader[2].ToString();
                }
                reader.Close();
            }
            catch { }

            if ((pDevice.InOut == 0) && (DB_SQLServer.b_Init))  //本地数据库未读取到，则根据门禁机序列号从远程数据库中读取门禁机名称、类型、排序号
            {
                try
                {
                    SqlDataReader reader = DB_SQLServer.ExecuteReader(string.Format("SELECT [BeaconName],[BeaType],[Line] FROM [T_JC_Beacon] WHERE [BeaMac] = '{0}'", strSN));

                    if (reader.Read())
                    {
                        pDevice.BeaconName = reader[0].ToString();
                        if (reader[1].ToString() == "JZWZLY004")
                        {
                            pDevice.InOut = 1;
                        }
                        else if (reader[1].ToString() == "JZWZLY005")
                        {
                            pDevice.InOut = 2;
                        }
                        pDevice.Position = reader[2].ToString();
                    }
                    reader.Close();
                }
                catch { }
            }
            
            lock (pDevice._Commandlocker)
            {
                //将每一天的时间规则统一改为0:00-24:00
                pDevice.CommandList.Enqueue("DATA DELETE timezone *");
                pDevice.CommandList.Enqueue("DATA UPDATE timezone FriTime1=2359\tFriTime2=0\tFriTime3=0\tHol1Time1=2359\tHol1Time2=0\tHol1Time3=0\tHol2Time1=2359\tHol2Time2=0\tHol2Time3=0\tHol3Time1=2359\tHol3Time2=0\tHol3Time3=0\tMonTime1=2359\tMonTime2=0\tMonTime3=0\tSatTime1=2359\tSatTime2=0\tSatTime3=0\tSunTime1=2359\tSunTime2=0\tSunTime3=0\tThuTime1=2359\tThuTime2=0\tThuTime3=0\tTueTime1=2359\tTueTime2=0\tTueTime3=0\tWedTime1=2359\tWedTime2=0\tWedTime3=0\tTimezoneId=1");
            }

            //根据排序号将门禁机加入门禁机列表
            int pos = 0;
            for (int i = 0; i < DeviceList.Count; i++)
            {
                if (string.Compare(DeviceList[i].Position, pDevice.Position) <= 0)
                {
                    pos++;
                }
                else
                {
                    break;
                }
            }
            DeviceList.Insert(pos, pDevice);

            return pDevice;
        }

        //数据处理函数
        private void ProcessData(ZKPUSH_Device pDevice, string[] arrRequestParam, string[] ContentStr)
        {
            string TableType = string.Empty;
            string TableName = string.Empty;
            for (int i = 2; i < arrRequestParam.Length; i++)
            {
                if (arrRequestParam[i].StartsWith("table="))
                {
                    TableType = arrRequestParam[i].Substring(6);        //表类型
                }
                else if (arrRequestParam[i].StartsWith("tablename="))
                {
                    TableName = arrRequestParam[i].Substring(10);       //表名
                }
            }

            if (TableType == "rtlog")                                   //门禁记录
            {
                for (int i = 0; i < ContentStr.Length; i++)
                {
                    Save_rtlog(pDevice, ContentStr[i]);
                }
            }
            else if (TableType == "tabledata")                          //表数据
            {
                for (int i = 0; i < ContentStr.Length; i++)
                {
                    Save_tabledata(pDevice, TableName, ContentStr[i]);
                }
            }
        }

        //保存门禁记录
        private void Save_rtlog(ZKPUSH_Device pDevice, string Data_rtlog)
        {
            string[] arr_rtlog = Data_rtlog.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
            string time = string.Empty, pin = string.Empty, cardno = string.Empty, eventaddr = string.Empty;
            string _event = string.Empty, inoutstatus = string.Empty, verifytype = string.Empty, index = string.Empty;

            for (int i = 0; i < arr_rtlog.Length; i++)
            {
                if (arr_rtlog[i].StartsWith("time="))
                {
                    time = arr_rtlog[i].Substring(5);           //时间
                }
                else if (arr_rtlog[i].StartsWith("pin="))
                {
                    pin = arr_rtlog[i].Substring(4);            //编号
                }
                else if (arr_rtlog[i].StartsWith("event="))
                {
                    _event = arr_rtlog[i].Substring(6);         //事件代码
                }
            }
            if ((pin != "0") && (int.Parse(_event) < 20))
            {
                GetRecord(pin, time, DeviceList.IndexOf(pDevice), pDevice.strSN, pDevice.BeaconName);
            }
        }

        //保存表数据
        private void Save_tabledata(ZKPUSH_Device pDevice, string TableName, string Data_table)
        {
            string[] arr_table = Data_table.Split(new char[] { '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries);
            string pin = string.Empty;
            for (int i = 0; i < arr_table.Length; i++)
            {
                if (arr_table[i].StartsWith("pin="))
                {
                    pin = arr_table[i].Substring(4);
                    break;
                }
            }

            if (pin.Length <= 0)
            {
                return;
            }

            string extra = GetUser(pin, "ZK");              //获取用户对应中控（ZK）设备的额外信息（人脸、指纹）
            ZKPUSH_UserInfo userinfo;
            if (extra.Length > 0)
            {
                userinfo = Data_Func.Deserialize(extra) as ZKPUSH_UserInfo;         //反序列化
            }
            else
            {
                userinfo = new ZKPUSH_UserInfo();
            }
             

            if (TableName == "user")                                        //用户表
            {
                for (int i = 0; i < arr_table.Length; i++)
                {
                    if (arr_table[i].StartsWith("password="))
                    {
                        userinfo.Password = arr_table[i].Substring(9);
                    }
                }
            }
            else if (TableName == "templatev10")                            //指纹表
            {
                ZKPUSH_Data newfinger = new ZKPUSH_Data();
                int fingerid = -1;
                for (int i = 0; i < arr_table.Length; i++)
                {
                    if (arr_table[i].StartsWith("fingerid="))
                    {
                        fingerid = int.Parse(arr_table[i].Substring(9));
                    }
                    else if (arr_table[i].StartsWith("size="))
                    {
                        newfinger.Size = arr_table[i].Substring(5);
                    }
                    else if (arr_table[i].StartsWith("valid="))
                    {
                        newfinger.Valid = arr_table[i].Substring(6);
                    }
                    else if (arr_table[i].StartsWith("template="))
                    {
                        newfinger.Buf = arr_table[i].Substring(9);
                    }
                }
                if (fingerid >= 0)
                {
                    userinfo.Finger[fingerid] = newfinger;
                }
            }
            else if (TableName == "facev7")                                 //人脸表
            {
                ZKPUSH_Data newface = new ZKPUSH_Data();
                int faceid = -1;
                for (int i = 0; i < arr_table.Length; i++)
                {
                    if (arr_table[i].StartsWith("faceid="))
                    {
                        faceid = int.Parse(arr_table[i].Substring(7));
                    }
                    else if (arr_table[i].StartsWith("size="))
                    {
                        newface.Size = arr_table[i].Substring(5);
                    }
                    else if (arr_table[i].StartsWith("valid="))
                    {
                        newface.Valid = arr_table[i].Substring(6);
                    }
                    else if (arr_table[i].StartsWith("face="))
                    {
                        newface.Buf = arr_table[i].Substring(5);
                    }
                    if (faceid >= 0)
                    {
                        userinfo.Face[faceid] = newface;
                    }
                }
            }

            extra = Data_Func.Serialize(userinfo);
            SaveUser(pin, "ZK", extra);                                         //保存用户额外信息
        }

        //生成注册码
        private static string createRegCode()
        {
            string regCode = GetRandomString(10, true, true, true, false, "");
            return regCode;
        }

        //生成会话ID
        private static string createSessionID()
        {
            string SessionID = GetRandomString(10, true, true, true, false, "");
            return SessionID;
        }

        //输出序列号、注册码与会话ID的整体校验和（未使用）
        private static string regCodeToken(string RegCode, string strSN, string SessionID)
        {
            String strSrc = RegCode + strSN + SessionID;
            byte[] strSrcByte = Encoding.Default.GetBytes(strSrc);
            MD5 md5 = new MD5CryptoServiceProvider();

            byte[] output = md5.ComputeHash(strSrcByte);
            string strToken = BitConverter.ToString(output).Replace("-", "");  //tbMd5pass为输出加密文本的文本框           
            return strToken;
        }

        //生成随机字符串
        private static string GetRandomString(int length, bool useNum, bool useLow, bool useUpp, bool useSpe, string custom)
        {
            byte[] b = new byte[4];
            new System.Security.Cryptography.RNGCryptoServiceProvider().GetBytes(b);
            Random r = new Random(BitConverter.ToInt32(b, 0));
            string s = null, str = custom;
            if (useNum == true) { str += "0123456789"; }
            if (useLow == true) { str += "abcdefghijklmnopqrstuvwxyz"; }
            if (useUpp == true) { str += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
            if (useSpe == true) { str += "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; }
            for (int i = 0; i < length; i++)
            {
                s += str.Substring(r.Next(0, str.Length - 1), 1);
            }
            return s;
        }

        //获取2000-1-1 00:00:00到当前时间的总秒数（门禁机内部的时间格式）
        private static string GetTimeSecond()
        {
            DateTime t = DateTime.Now;
            return ((((((t.Year - 2000) * 12 + (t.Month - 1)) * 31 + (t.Day - 1)) * 24 + t.Hour) * 60 + t.Minute) * 60 + t.Second).ToString();
        }

        //根据序列号从门禁机列表中读取对应门禁机
        private ZKPUSH_Device GetDevice(string strSN)
        {
            for (int i = 0; i < DeviceList.Count; i++)
            {
                if (strSN == DeviceList[i].strSN)
                {
                    return DeviceList[i];
                }
            }
            return null;
        }

        //根据内容构造回复数据包并发送
        private void SendReply(string ReplyStr, ref Socket mySocket)
        {
            String sBuffer = null;

            sBuffer += "HTTP/1.1 200 OK\r\n";                                                               //HTTP协议与状态
            sBuffer += "Server: DIMINE_KC_SERVER \r\n";                                                     //服务器名
            sBuffer += "Date: " + DateTime.UtcNow.GetDateTimeFormats('r')[0].ToString() + "\r\n";           //时间，UTC格式
            sBuffer += "Content-Type: application/push;UTF-8\r\n";                                          //协议类型 编码
            sBuffer += "Content-Length: " + Encoding.GetEncoding("utf-8").GetBytes(ReplyStr).Length +"\r\n";//内容长度
            sBuffer += "Connection: keep-alive\r\n\r\n";                                                    //连接方式
            sBuffer += ReplyStr;

            Byte[] bSendData = Encoding.GetEncoding("utf-8").GetBytes(sBuffer);

            try
            {
                if (mySocket.Connected)
                {
                    mySocket.Send(bSendData, bSendData.Length, 0);
                    mySocket.Close();
                }
            }
            catch { }
        }
    }
}
